<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Microcontroller Power Management</title>
<meta name="author" content="Robert Szewczyk, Philip Levis, Martin Turon, Lama Nachman, Philip Buonadonna, Vlado Handziski" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2007-08-14 18:58:01 $
:version: $Revision: 1.6 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/
body {
  font-family: Times;
  font-size: 16px;
}

.first {
  margin-top: 0 ! important }

.last {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1 {
  font-family: Arial, sans-serif;
  font-size: 20px;
}

h1.title {
 text-align: center;
 font-size: 32px;
}

h2 {
 font-size: 16px;
 font-family: Arial, sans-serif;
}

h2.subtitle {
  text-align: center }

h3 {
 font-size: 12px;
 font-family: Arial, sans-serif;
}

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee;
  border-color: #000000;
  border-width: thin; 
  font-size: 14px
}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em;
}

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap;
  }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {}

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="microcontroller-power-management">
<h1 class="title">Microcontroller Power Management</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">112</td>
</tr>
<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">Core Working Group</td>
</tr>
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Robert Szewczyk, Philip Levis, Martin Turon, Lama Nachman, Philip Buonadonna, Vlado Handziski</td></tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo documents a part of TinyOS for the TinyOS Community, and
requests discussion and suggestions for improvements.  Distribution
of this memo is unlimited. This memo is in full compliance with
TEP 1.</p>
</div>
<div class="section" id="abstract">
<h1>Abstract</h1>
<p>This memo documents how TinyOS manages the lower power state of a
microcontroller.</p>
</div>
<div class="section" id="introduction">
<h1>1. Introduction</h1>
<p>Microcontrollers often have several power states, with varying power
draws, wakeup latencies, and peripheral support. The microcontroller
should always be in the lowest possible power state that can satisfy
application requirements. Determining this state accurately requires
knowing a great deal about the power state of many subsystems and
their peripherals. Additionally, state transitions are common. Every
time a microcontroller handles an interrupt, it moves from a low power
state to an active state, and whenever the TinyOS scheduler finds the
task queue empty it returns the microcontroller to a low power state.
TinyOS 2.x uses three mechanisms to decide what low power state it
puts a microcontroller into: status and control registers, a dirty
bit, and a power state override. This memo documents these mechanisms
and how they work, as well as the basics of subsystem power
management.</p>
</div>
<div class="section" id="background">
<h1>2. Background</h1>
<p>The TinyOS scheduler[<a class="reference internal" href="#id3">2</a>] puts a processor into a sleep state when
the task queue is empty. However, processors can have a spectrum of
power states. For example, the MSP430 has one active mode (issuing
instructions) and five low-power modes. The low power modes range from
LPM0, which disables only the CPU and main system clock, to LPM4,
which disables the CPU, all clocks, and the oscillator, expecting to
be woken by an external interrupt source. The power draws of these low
power modes can differ by a factor of 350 or more (75 uA for LPM0 at
3V, 0.2 uA for LPM4). Correctly choosing the right microcontroller low
power state can greatly increase system lifetime.</p>
<p>TinyOS 1.x platforms manage MCU power in several different ways, but
there are commonalities in the approaches. The mica platforms, for
example, have a component named HPLPowerManagement, which has a
commands for enabling and disabling low power modes, as well as a
command (adjustPower()) to tell it to compute the low power state
based on the configuration of its various control and status
registers, storing the result in the Atmega128's MCU control
register. When TinyOS tells the microcontroller to go to sleep, it
uses the control register to decide exactly which power state to go
into. In contrast, MSP430 based platforms such as Telos and eyes
compute the low power state every time the scheduler tells the system
to go to sleep.</p>
<p>Each of the two approaches has benefits and drawbacks. The 1.x mica
approach is efficient, in that it only calculates the low power state
when told to. However, this leaves the decision of when to calculate
the low power state to other components, which is an easy way to
introduce bugs. The lack of a well-defined hardware abstraction
architecture in 1.x exacerbates this problem. In contrast, the MSP430
approach is simpler, in that the system will always enter the right
power state without any external prompting. However, it is
correspondingly costly, introducing 40-60 cycles of overhead to every
interrupt that wakes the system up, which can be a bottleneck on the rate
at which the system can handle interrupts.</p>
<p>Both of these approaches assume that TinyOS can determine the correct
low power state by examining control and status registers. For
example, the MSP430 defaults to low power mode 3 (LPM3) unless it
detects that Timer A, the USARTs, or the ADC is active, in which case
it uses low power mode 1 (LPM1). From the perspective of what
peripherals and subsystems might wake the node up or must continue
operating while the MCU sleeps, this is true. However, power modes
introduce wakeup latency, a factor which could be of interest to
higher-level components. While wakeup latency is not a significant
issue on very low power microcontrollers, such as the Atmega128 and
MSP430, more powerful processors, such as the Xscale family (the basis
of platforms such as the imote2) can have power states with wakeup
latencies as large as 5ms. For some application domains, this latency
could be a serious issue. Higher level components therefore need a way
to give the TinyOS microcontroller power manager information on their
requirements, which it considers when calculating the right low power
state.</p>
</div>
<div class="section" id="id1">
<h1>3. Microcontroller Power Management</h1>
<p>TinyOS 2.x uses three basic mechanisms to manage and control
microcontroller power states: a dirty bit, a chip-specific low power
state calculation function, and a power state override function.  The
dirty bit tells TinyOS when it needs to calculate a new low power
state, the function performs the calculation, and the override allows
higher level components to introduce additional requirements, if
needed.</p>
<p>These three mechanisms all operate in the TinyOS core scheduling loop,
described in TEP 106: Schedulers and Tasks[<a class="reference internal" href="#id3">2</a>]. This loop is
called from the boot sequence, which is described in TEP 107: Boot
Sequence[<a class="reference internal" href="#id4">3</a>]. The command in question is
<tt class="docutils literal">Scheduler.taskLoop()</tt>, when microcontroller sleeping is enabled.</p>
<p>If this command is called when the task queue is empty, the TinyOS
scheduler puts the microcontroller to sleep. It does so through
the <tt class="docutils literal">McuSleep</tt> interface:</p>
<div class="line-block">
<div class="line"><tt class="docutils literal">interface McuSleep {</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">async command void <span class="pre">sleep();</span></tt></div>
</div>
<div class="line"><tt class="docutils literal">}</tt></div>
</div>
<p><tt class="docutils literal">McuSleep.sleep()</tt> puts the microcontroller into a low power sleep
state, to be woken by an interrupt. This command deprecates the
<tt class="docutils literal">__nesc_atomic_sleep()</tt> call of TinyOS 1.x. Note that, as the 1.x
call suggests, putting the microcontroller to sleep MUST have certain
atomicity properties. The command is called from within an atomic
section, and MUST atomically re-enable interrupts and go to sleep. An
issue arises if the system handles an interrupt after it re-enables
interrupts but before it sleeps: the interrupt may post a task, but
the task will not be run until the microcontroller wakes up from sleep.</p>
<p>Microcontrollers generally have hardware mechanisms to support this
requirement. For example, on the Atmega128, the <tt class="docutils literal">sei</tt> instruction
does not re-enable interrupts until two cycles after it is issued (so
the sequence <tt class="docutils literal">sei sleep</tt> runs atomically).</p>
<p>A component named <tt class="docutils literal">McuSleepC</tt> provides the McuSleep interface, and
<tt class="docutils literal">TinySchedulerC</tt> MUST automatically wire it to the scheduler
implementation. McuSleepC is a chip- or platform-specific component,
whose signature MUST include the following interfaces:</p>
<div class="line-block">
<div class="line"><tt class="docutils literal">component McuSleepC {</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">provides interface McuSleep;</tt></div>
<div class="line"><tt class="docutils literal">provides interface PowerState;</tt></div>
<div class="line"><tt class="docutils literal">uses interface PowerOverride;</tt></div>
</div>
<div class="line"><tt class="docutils literal">}</tt></div>
<div class="line"><br /></div>
<div class="line"><tt class="docutils literal">interface McuPowerState {</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">async command void <span class="pre">update();</span></tt></div>
</div>
<div class="line"><tt class="docutils literal">}</tt></div>
<div class="line"><br /></div>
<div class="line"><tt class="docutils literal">interface McuPowerOverride {</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">async command mcu_power_t <span class="pre">lowestState();</span></tt></div>
</div>
<div class="line"><tt class="docutils literal">}</tt></div>
</div>
<p>McuSleepC MAY have additional interfaces.</p>
</div>
<div class="section" id="the-dirty-bit">
<h1>3.1 The Dirty Bit</h1>
<p>Whenever a Hardware Presentation Layer (HPL, see TEP 2: Hardware
Abstraction Architecture[<a class="reference internal" href="#id2">1</a>]) component changes an aspect of
hardware configuration that might change the possible low power state
of the microcontroller, it MUST call McuPowerState.update(). This is
the first power management mechanism, a <em>dirty bit</em>. If
McuPowerState.update() is called, then McuSleepC MUST recompute the
low power state before the next time it goes to sleep as a result of
McuSleep.sleep() being called.</p>
</div>
<div class="section" id="low-power-state-calculation">
<h1>3.2 Low Power State Calculation</h1>
<p>McuSleepC is responsible for calculating the lowest power state that
it can safely put the microcontroller into without disrupting the
operation of TinyOS subsystems. McuSleepC SHOULD minimize how often it
must perform this calculation: it is an inherently atomic calculation,
and so if performed very often (e.g., on every interrupt) can
introduce significant overhead and jitter.</p>
<p>MCU power states MUST be represented as an enum in the standard chip
implementation header file. This file MUST also define a type
<tt class="docutils literal">mcu_power_t</tt> and a combine function that given two power state
values returns one that provides the union of their functionality.</p>
<p>For example, consider a hypothetical microcontroller with three low
power states, (LPM0, LPM1, LPM2) and two hardware resources such as
clocks (HR0, HR1). In LPM0, both HR0 and HR1 are active. In LPM1, HR0
is inactive but HR1 is active. In LPM2, both HR0 and HR1 are inactive.
The following table describes the results of a proper combine function
(essentially a MAX):</p>
<table border="1" class="docutils">
<colgroup>
<col width="25%" />
<col width="25%" />
<col width="25%" />
<col width="25%" />
</colgroup>
<tbody valign="top">
<tr><td>&nbsp;</td>
<td>LPM0</td>
<td>LPM1</td>
<td>LPM2</td>
</tr>
<tr><td>LPM0</td>
<td>LPM0</td>
<td>LPM0</td>
<td>LPM0</td>
</tr>
<tr><td>LPM1</td>
<td>LPM0</td>
<td>LPM1</td>
<td>LPM1</td>
</tr>
<tr><td>LPM2</td>
<td>LPM0</td>
<td>LPM1</td>
<td>LPM2</td>
</tr>
</tbody>
</table>
<p>In contrast, if in LPM2, HR0 is active but HR1 is inactive, the
combine function would look like this:</p>
<table border="1" class="docutils">
<colgroup>
<col width="25%" />
<col width="25%" />
<col width="25%" />
<col width="25%" />
</colgroup>
<tbody valign="top">
<tr><td>&nbsp;</td>
<td>LPM0</td>
<td>LPM1</td>
<td>LPM2</td>
</tr>
<tr><td>LPM0</td>
<td>LPM0</td>
<td>LPM0</td>
<td>LPM0</td>
</tr>
<tr><td>LPM1</td>
<td>LPM0</td>
<td>LPM1</td>
<td>LPM0</td>
</tr>
<tr><td>LPM2</td>
<td>LPM0</td>
<td>LPM0</td>
<td>LPM2</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="power-state-override">
<h1>3.3 Power State Override</h1>
<p>When McuSleepC computes the best low power state, it MUST call
<tt class="docutils literal"><span class="pre">PowerOverride.lowestState().</span></tt> McuSleepC SHOULD have a default
implementation of this command, which returns the lowest power state
the MCU is capable of. The return value of this command is a
<tt class="docutils literal">mcu_power_t.</tt> McuSleepC MUST respect the requirements of the return
of this call and combine it properly with the low power state it
computes.</p>
<p>The PowerOverride functionality exists in case higher-level components
have some knowledge or requirements that cannot be captured in
hardware status and configuration registers, such as a maximum
tolerable wakeup latency. Because it can overrides all of the MCU
power conservation mechanisms, it SHOULD be used sparingly, if at
all. Because it is called in an atomic section during the core
scheduling loop, implementations of PowerOverride.lowestState() SHOULD
be an efficient function, and SHOULD NOT be longer than twenty or
thirty cycles; implementations SHOULD be a simple return of a cached
variable. Wiring arbitrarily to this command is an easy way to cause
TinyOS to behave badly. The presence of a combine function for
mcu_power_t means that this command can have fan-out calls.</p>
<p>Section 5 describes one example use of McuPowerOverride, in the
timer stack for the Atmega128 microcontroller family.</p>
<p>As part of power state override, a platform MUST define the enum
TOS_SLEEP_NONE in its hardware.h file. This enum defines the highest
power state of the platform's microcontroller in a chip-independent
way. If a component wires to McuPowerOverride and returns TOS_SLEEP_NONE,
this will cause TinyOS to never put the microcontroller into a power
saving state. This enum allows a component to prevent sleep in a
platform-independent way.</p>
</div>
<div class="section" id="peripherals-and-subsystems">
<h1>4. Peripherals and Subsystems</h1>
<p>At the HIL level, TinyOS subsystems generally have a simple,
imperative power management interface. Depending on the latencies
involved, this interface is either <tt class="docutils literal">StdControl</tt>, <tt class="docutils literal">SplitControl</tt>,
or <tt class="docutils literal">AsyncStdControl</tt>.
These interfaces are imperative in that when any component calls
<tt class="docutils literal">stop</tt> on another component, it causes the subsystem that
component represents to enter an inactive, low-power state.</p>
<p>From the perspective of MCU power management, this transition causes a
change in status and control registers (e.g., a clock is
disabled). Following the requirements in 3.1, the MCU power management
subsystem will be notified of a significant change and act
appropriately when the system next goes to sleep. TEP 115[<a class="reference internal" href="#id6">5</a>]
describes the power management of non-virtualized devices in
greater detail, and TEP 108[<a class="reference internal" href="#id5">4</a>] describes how TinyOS can automatically
include power management into shared non-virtualized devices.</p>
</div>
<div class="section" id="implementation">
<h1>5. Implementation</h1>
<p>An implementation of McuSleepC can be found in <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/atm128</span></tt>,
<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/msp430</span></tt>, and <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/px27ax</span></tt>.</p>
<p>An example use of McuPowerOverride can be found in the atmega128 timer
system. Because some low-power states have much longer wakeup latencies than
others, the timer system does not allow long latencies if it has a timer
that is going to fire soon.  The implementation can be found in
<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/atm128/timer/HplAtm128Timer0AsyncP.nc</span></tt>, and
<tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/atm128/timer/HplAtm128Timer0AsyncC.nc</span></tt> automatically
wires it to McuSleepC if it is included.</p>
<p>For the atmega128 microcontroller, TOS_SLEEP_NONE is the &quot;idle&quot; power
state.</p>
<p>A second example use of McuPowerOverride is in the msp430 timer system.
By default, the msp430 lowest power state is LPM4, which does not keep
clocks enabled. If <tt class="docutils literal"><span class="pre">tinyos-2.x/tos/chips/msp430/timer/Msp430ClockC.nc''</span>
is included in the component graph, however, this configuration wires
the McuPowerOverride of <span class="pre">``tinyos-2.x/tos/chips/msp430/timer/Msp430ClockP.nc</span></tt>
to McuSleepC. This implemementation of McuPowerOverride raises the lowest
power state to LPM3, which keeps clocks enabled.</p>
<p>For msp430 microcontrollers, TOS_SLEEP_NONE is the &quot;active&quot; power state.</p>
</div>
<div class="section" id="author-s-address">
<h1>6. Author's Address</h1>
<div class="line-block">
<div class="line">Robert Szewczyk</div>
<div class="line">Moteiv Corporation</div>
<div class="line">2168 Shattuck Ave, Floor 2</div>
<div class="line">Berkeley, CA 94704</div>
<div class="line"><br /></div>
<div class="line">email - <a class="reference external" href="mailto:rob&#64;moteiv.com">rob&#64;moteiv.com</a></div>
<div class="line"><br /></div>
<div class="line"><br /></div>
<div class="line">Philip Levis</div>
<div class="line">358 Gates</div>
<div class="line">Computer Science Laboratory</div>
<div class="line">Stanford University</div>
<div class="line">Stanford, CA 94305</div>
<div class="line"><br /></div>
<div class="line">phone - +1 650 725 9046</div>
<div class="line">email - <a class="reference external" href="mailto:pal&#64;cs.stanford.edu">pal&#64;cs.stanford.edu</a></div>
<div class="line"><br /></div>
<div class="line"><br /></div>
<div class="line">Martin Turon</div>
<div class="line">PO Box 8525</div>
<div class="line">Berkeley, CA 94707</div>
<div class="line"><br /></div>
<div class="line">phone - +1 408 965 3355</div>
<div class="line">email - <a class="reference external" href="mailto:mturon&#64;xbow.com">mturon&#64;xbow.com</a></div>
<div class="line"><br /></div>
<div class="line"><br /></div>
<div class="line">Lama Nachman</div>
<div class="line">3600 Juliette Lane, SC12-319</div>
<div class="line">Intel Research</div>
<div class="line">Santa Clara, CA 95052</div>
<div class="line"><br /></div>
<div class="line">email - <a class="reference external" href="mailto:lama.nachman&#64;intel.com">lama.nachman&#64;intel.com</a></div>
<div class="line"><br /></div>
<div class="line"><br /></div>
<div class="line">Phil Buonadonna</div>
<div class="line">Arched Rock Corp.</div>
<div class="line">2168 Shattuck Ave. 2nd Floor</div>
<div class="line">Berkeley, CA 94704</div>
<div class="line"><br /></div>
<div class="line">phone - +1 510 981 8714</div>
<div class="line">email - <a class="reference external" href="mailto:pbuonadonna&#64;archedrock.com">pbuonadonna&#64;archedrock.com</a></div>
<div class="line"><br /></div>
<div class="line"><br /></div>
<div class="line">Vlado Handziski</div>
<div class="line">Sekr FT5</div>
<div class="line">Einsteinufer 25</div>
<div class="line">10587 Berlin</div>
<div class="line">GERMANY</div>
<div class="line"><br /></div>
<div class="line">email - <a class="reference external" href="mailto:handzisk&#64;tkn.tu-berlin.de">handzisk&#64;tkn.tu-berlin.de</a></div>
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="citations">
<h1>6. Citations</h1>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[1]</td><td>TEP 2: Hardware Abstraction Architecture</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id3" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[2]</td><td>TEP 106: Schedulers and Tasks.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[3]</td><td>TEP 107: TinyOS 2.x Boot Sequence.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[4]</td><td>TEP 108: Resource Arbitration</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id6" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[5]</td><td>TEP 115: Power Management of Non-Virtualised Devices</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
